#include <iostream>
#include <vector>
#include <time.h>
#include <thread>
#include <atomic>
#include <functional>

#include <algorithm>
using namespace std;

vector<int8_t> testdata(10000 * 10000);
vector<int8_t> testtodata(10000 * 10000);

uint64_t t1, t2, tc;

void time_begin()
{
    t1 = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
}

float time_end()
{
    t2 = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
    return (t2 - t1);
}
int main(int argc, char **argv)
{
    cout << "start" << endl;

    for (size_t i = 0; i < testdata.size(); i++) { testdata[i] = i % 255; }
    int chip_count = thread::hardware_concurrency();
    int chip_size  = 10000 * 10000 / chip_count;
    vector<thread> threads(chip_count-1);
    time_begin();
    for (int i = 0; i < chip_count - 1; i++)
    {
        threads[i] = thread([&, i]() { std::copy(testdata.begin() + (i * chip_size), testdata.begin() + ((i + 1) * chip_size), testtodata.begin() + (i * chip_size));});
    }
    std::copy(testdata.begin() + ((chip_count - 1) * chip_size), testdata.end(), testtodata.begin() + (((chip_count - 1)) * chip_size));
    std::for_each(threads.begin(), threads.end(), std::mem_fn(&thread::join));
    cout << "time: " << time_end() << endl;

    time_begin();
    std::copy(testdata.begin(), testdata.end(), testtodata.begin());
    cout << "time: " << time_end() << endl;

    return 0;
}